package com.longqin.wechat.jwt;

import java.util.Map;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;

import com.auth0.jwt.interfaces.Claim;
import com.longqin.wechat.util.MyObjectUtil;

@Component
public class MyRealm extends AuthorizingRealm {
	
    /**
     * 大坑！，必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }

    /**
     * 只有当需要检测用户权限的时候才会调用此方法，例如checkRole,checkPermission之类的
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    /**
     * 默认使用此方法进行用户名正确与否验证，错误抛出异常即可。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        String token = (String) auth.getCredentials();
        if(!MyObjectUtil.isNotNull(token)) throw new AuthenticationException("token认证失败");
        Map<String,Claim> map = JWTUtil.getJWTClaim(token);//从token中获取用户信息
        if(null == map || !map.get("tokenType").asString().equals("access_token") || !JWTUtil.verify(token)){
        	throw new AuthenticationException("token认证失败");
        }
        //不进行数据库效验，不然每次请求都查询很费数据库资源，只有登录成功的用户才能获取token
        return new SimpleAuthenticationInfo(token, token, "MyRealm");
    }
}
